#include "timer.h"
#include "io.h"
#include "print.h"
#include "stdint.h"
#include "../thread/thread.h"

#define IRQ0_FREQUENCY	   100
#define INPUT_FREQUENCY	   1193180
#define COUNTER0_VALUE	   INPUT_FREQUENCY / IRQ0_FREQUENCY
#define COUNTER0_PORT	   0x40
#define COUNTER0_NO	   0
#define COUNTER_MODE	   2
#define READ_WRITE_LATCH   3
#define PIT_CONTROL_PORT   0x43

uint32_t ticks = 0;

static void frequency_set(uint8_t counter_port, \
			  uint8_t counter_no, \
			  uint8_t read_write_lock, \
			  uint8_t counter_mode, \
			  uint16_t counter_value)
{

	outb(PIT_CONTROL_PORT, (uint8_t)(counter_no << 6 | read_write_lock << 4 | counter_mode << 1));
	outb(counter_port, (uint8_t)counter_value);
	outb(counter_port, (uint8_t)counter_value >> 8);
}

static void timer_intr(int8_t intr_num)
{
	struct task_pcb* pcb = running_thread();
	
	++ticks;
	++pcb->total_ticks;
	
	if (pcb->ticks > 0)
	{
		--pcb->ticks;
	}
	else
	{
		schedule();
	}
}

void timer_init()
{
	frequency_set(COUNTER0_PORT, COUNTER0_NO, READ_WRITE_LATCH, COUNTER_MODE, COUNTER0_VALUE);
	
	register_intr_handler(0x20, timer_intr);

	print_string("timer_init done\n");
}
